#include "stdafx.h"
#include "DDrawPrimary.h"

#define COMPILE_MULTIMON_STUBS 
#include <multimon.h>

DDrawPrimary g_xDDrawPrimary;

DDrawPrimary::DDrawPrimary(void)
{
	m_bInit = FALSE;
	EnumMonitor();
}

DDrawPrimary::~DDrawPrimary(void)
{
	UnInitPrimary();
}

void DDrawPrimary::UnInitPrimary()
{
	TG_AUTO_LOCK xLock(&m_Sect);

	ScreenMon *pMon = NULL;
	for(int i=0;i<m_nScreenCount;i++)
	{
		pMon = &m_xScreenMon[i];
		if( NULL != pMon->pDDSOverlay )
		{
			pMon->pDDSOverlay->Release();
			pMon->pDDSOverlay = NULL;
		}
        if( NULL != pMon->pDDSFront )
		{
			pMon->pDDSFront->Release();
			pMon->pDDSFront = NULL;
		}
		if( NULL != pMon->pDD )
		{
			pMon->pDD->Release();
			pMon->pDD = NULL;
		}
	}
	m_bInit = FALSE;
}


BOOL DDrawPrimary::_DDEnumCallback(GUID FAR * pGUID, LPSTR pName, LPSTR pDescription,  LPVOID pUserData, HMONITOR hMonitor)
{ 
	DDrawPrimary *pDDraw = (DDrawPrimary*)pUserData;
	if( NULL != pDDraw )
	{
        return pDDraw->DDEnumCallback(pGUID,pName,pDescription,hMonitor);
	}
	return DDENUMRET_OK;
}


BOOL DDrawPrimary::DDEnumCallback(GUID FAR * pGUID, LPSTR pName, LPSTR pDescription, HMONITOR hMonitor)
{
	if( pGUID != NULL && m_nScreenCount < DVR_MONITOR_COUNT-1 )
	{
		m_xScreenMon[m_nScreenCount].guid     = *pGUID;
		m_xScreenMon[m_nScreenCount].hMonitor = hMonitor;
		m_nScreenCount ++;
	}
	return TRUE;
}

void DDrawPrimary::EnumMonitor()
{
	m_nScreenCount = 0;
	DirectDrawEnumerateEx(_DDEnumCallback, this, DDENUM_ATTACHEDSECONDARYDEVICES | DDENUM_NONDISPLAYDEVICES);
}

int DDrawPrimary::InitPrimary(HWND hWnd)
{
	if( m_bInit )
	{
		return DD_OK;
	}
	UnInitPrimary();

	TG_AUTO_LOCK xLock(&m_Sect);
	
	HRESULT hr;
	
	do 
	{
		if( NULL == hWnd )
		{
            return DD_FALSE;
		}
		if( m_nScreenCount < 1 )
		{
			m_nScreenCount = 1;
		}

		DWORD   dwFlags = DDSCL_NORMAL;
		DDSURFACEDESC2 ddsd; 

		ScreenMon *pMon = NULL;
		for(int i=0;i<m_nScreenCount;i++)
		{
			pMon = &m_xScreenMon[i];
			hr = DirectDrawCreateEx( &pMon->guid, (VOID**)&(pMon->pDD), IID_IDirectDraw7, NULL );
			if( FAILED(hr) || NULL == pMon->pDD )
			{
				goto __ERR_EXIT;
			}
			hr = pMon->pDD->SetCooperativeLevel( hWnd, dwFlags );
			if( FAILED(hr) )
			{
				goto __ERR_EXIT;
			}
			
			ZeroMemory(&ddsd, sizeof(ddsd));
			ddsd.dwSize  = sizeof(ddsd);
			ddsd.dwFlags = DDSD_CAPS;
			ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
			hr = pMon->pDD->CreateSurface(&ddsd, &pMon->pDDSFront, NULL);
			if( FAILED(hr) || NULL == pMon->pDDSFront )
			{
				goto __ERR_EXIT;
			}
		}

		m_bInit = TRUE;

		return DD_OK;

	} while (false);

__ERR_EXIT:
	return hr;
}
